home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_01 / erdelsky / endian.h < prev   
C/C++ Source or Header  |  1994-10-31  |  6KB  |  239 lines

  1.                            The File ENDIAN.H
  2.                             (a first draft)
  3.  
  4. // Portable Byte Ordering in C++
  5. // by Philip J. Erdelsky
  6. // Public Domain -- No Restrictions on Use
  7.  
  8. // If the byte order of the target machine is known, include ONE of
  9. // the following statements:
  10. //   #define _BIG_ENDIAN
  11. //   #define _LITTLE_ENDIAN
  12.  
  13. // If the byte order of the target machine is to be determined at run
  14. // time for each conversion, include the following statement:
  15. //   #define _RUN_TIME_ENDIAN
  16.  
  17. #ifndef _ENDIAN
  18. #define _ENDIAN 1
  19.  
  20. typedef unsigned char BYTE;
  21. typedef unsigned short WORD;  // two-byte word
  22. typedef unsigned long DWORD;  // four-byte double word
  23.  
  24. #ifdef _RUN_TIME_ENDIAN
  25.  
  26.   extern union _endian_union
  27.   {
  28.     DWORD whole;
  29.     WORD half[2];
  30.   } _endian;
  31.  
  32.   inline int big_endian(void) {return _endian.half[1];}
  33.   inline int little_endian(void) {return _endian.half[0];}
  34.  
  35. #endif
  36.  
  37. // check for consistent parameter definitions
  38.  
  39. #ifdef _BIG_ENDIAN
  40.   #ifdef _LITTLE_ENDIAN
  41.     #error _BIG_ENDIAN and _LITTLE_ENDIAN both defined
  42.   #endif
  43.   #ifdef __RUN_TIME_ENDIAN
  44.     #error _BIG_ENDIAN and _RUN_TIME_ENDIAN both defined
  45.   #endif
  46. #endif
  47.  
  48. #ifdef _LITTLE_ENDIAN
  49.   #ifdef __RUN_TIME_ENDIAN
  50.     #error _LITTLE_ENDIAN and _RUN_TIME_ENDIAN both defined
  51.   #endif
  52. #endif
  53.  
  54.  
  55. class BEWORD  // big endian WORD
  56. {
  57.     union
  58.     {
  59.       BYTE half[2];
  60.       WORD whole;
  61.     } x;
  62.   public:
  63.     void set(WORD n)
  64.     {
  65.       #ifdef _BIG_ENDIAN
  66.         x.whole = n;
  67.       #else
  68.         #ifdef _RUN_TIME_ENDIAN
  69.           if (big_endian()) x.whole = n;
  70.           else {
  71.         #endif
  72.         x.half[0] = n >> 8;
  73.         x.half[1] = n;
  74.         #ifdef _RUN_TIME_ENDIAN
  75.           }
  76.         #endif
  77.       #endif
  78.     }
  79.     BEWORD(WORD n) {set(n);}
  80.     WORD value(void)
  81.     {
  82.       return
  83.         #ifdef _BIG_ENDIAN
  84.           x.whole
  85.         #else
  86.           #ifdef _RUN_TIME_ENDIAN
  87.             big_endian() ? x.whole :
  88.           #endif
  89.           x.half[0] << 8 | x.half[1]
  90.         #endif
  91.           ;
  92.     }
  93.     int zero(void) {return x.whole == 0;}
  94.     int nonzero(void) {return x.whole != 0;}
  95.     int operator == (BEWORD &n) {return x.whole == n.x.whole;}
  96.     int operator != (BEWORD &n) {return x.whole != n.x.whole;}
  97. };
  98.  
  99. class BEDWORD  // big endian DWORD
  100. {
  101.     union
  102.     {
  103.       BYTE quarter[4];
  104.       DWORD whole;
  105.     } x;
  106.   public:
  107.     void set(DWORD n)
  108.     {
  109.       #ifdef _BIG_ENDIAN
  110.         x.whole = n;
  111.       #else
  112.         #ifdef _RUN_TIME_ENDIAN
  113.           if (big_endian()) x.whole = n;
  114.           else {
  115.         #endif
  116.         x.quarter[0] = n >> 24;
  117.         x.quarter[1] = n >> 16;
  118.         x.quarter[2] = n >> 8;
  119.         x.quarter[3] = n;
  120.         #ifdef _RUN_TIME_ENDIAN
  121.           }
  122.         #endif
  123.       #endif
  124.     }
  125.     BEDWORD(DWORD n) {set(n);}
  126.     DWORD value(void)
  127.     {
  128.       return
  129.         #ifdef _BIG_ENDIAN
  130.           x.whole
  131.         #else
  132.           #ifdef _RUN_TIME_ENDIAN
  133.             big_endian() ? x.whole :
  134.           #endif
  135.           (DWORD) x.quarter[0] << 24 | (DWORD) x.quarter[1] << 16 |
  136.              x.quarter[2] << 8 | x.quarter[3];
  137.         #endif
  138.           ;
  139.     }
  140.     int zero(void) {return x.whole == 0;}
  141.     int nonzero(void) {return x.whole != 0;}
  142.     int operator == (BEDWORD &n) {return x.whole == n.x.whole;}
  143.     int operator != (BEDWORD &n) {return x.whole != n.x.whole;}
  144. };
  145.  
  146. class LEWORD  // little endian WORD
  147. {
  148.     union
  149.     {
  150.       BYTE half[2];
  151.       WORD whole;
  152.     } x;
  153.   public:
  154.     void set(WORD n)
  155.     {
  156.       #ifdef _LITTLE_ENDIAN
  157.         x.whole = n;
  158.       #else
  159.         #ifdef _RUN_TIME_ENDIAN
  160.           if (little_endian()) x.whole = n;
  161.           else {
  162.         #endif
  163.         x.half[1] = n >> 8;
  164.         x.half[0] = n;
  165.         #ifdef _RUN_TIME_ENDIAN
  166.           }
  167.         #endif
  168.       #endif
  169.     }
  170.     LEWORD(WORD n) {set(n);}
  171.     WORD value(void)
  172.     {
  173.       return
  174.         #ifdef _LITTLE_ENDIAN
  175.           x.whole
  176.         #else
  177.           #ifdef _RUN_TIME_ENDIAN
  178.             little_endian() ? x.whole :
  179.           #endif
  180.           x.half[1] << 8 | x.half[0]
  181.         #endif
  182.           ;
  183.     }
  184.     int zero(void) {return x.whole == 0;}
  185.     int nonzero(void) {return x.whole != 0;}
  186.     int operator == (LEWORD &n) {return x.whole == n.x.whole;}
  187.     int operator != (LEWORD &n) {return x.whole != n.x.whole;}
  188. };
  189.  
  190. class LEDWORD  // little endian DWORD
  191. {
  192.     union
  193.     {
  194.       BYTE quarter[4];
  195.       DWORD whole;
  196.     } x;
  197.   public:
  198.     void set(DWORD n)
  199.     {
  200.       #ifdef _LITTLE_ENDIAN
  201.         x.whole = n;
  202.       #else
  203.         #ifdef _RUN_TIME_ENDIAN
  204.           if (little_endian()) x.whole = n;
  205.           else {
  206.         #endif
  207.         x.quarter[0] = n;
  208.         x.quarter[1] = n >> 8;
  209.         x.quarter[2] = n >> 16;
  210.         x.quarter[3] = n >> 24;
  211.         #ifdef _RUN_TIME_ENDIAN
  212.           }
  213.         #endif
  214.       #endif
  215.     }
  216.     LEDWORD(DWORD n) {set(n);}
  217.     DWORD value(void)
  218.     {
  219.       return
  220.         #ifdef _LITTLE_ENDIAN
  221.           x.whole
  222.         #else
  223.           #ifdef _RUN_TIME_ENDIAN
  224.             little_endian() ? x.whole :
  225.           #endif
  226.           x.quarter[0] | x.quarter[1] << 8 |
  227.             (DWORD) x.quarter[2] << 16 | (DWORD) x.quarter[3] << 24;
  228.         #endif
  229.           ;
  230.     }
  231.     int zero(void) {return x.whole == 0;}
  232.     int nonzero(void) {return x.whole != 0;}
  233.     int operator == (LEDWORD &n) {return x.whole == n.x.whole;}
  234.     int operator != (LEDWORD &n) {return x.whole != n.x.whole;}
  235. };
  236.  
  237. #endif
  238.  
  239.